import { m, AnimatePresence } from "framer-motion";
import * as RadixPopover from "@radix-ui/react-popover";
import { isValidElement, ReactElement, ReactNode, useState } from "react";
import { clsxm } from "../helpers";
import { Close as CloseIcon } from "../icons";

type PopoverProps = {
  trigger: ReactElement;
  children?: ReactNode;
  contentClassName?: string;
  title?: ReactNode;
  placement?: RadixPopover.PopoverContentProps["side"];
  align?: RadixPopover.PopoverContentProps["align"];
  showClose?: boolean;
  open?: boolean;
  onOpenChange?: (open: boolean) => void;
};

export function Popover(props: PopoverProps) {
  const {
    trigger,
    children,
    contentClassName,
    title,
    placement = "bottom",
    align = "center",
    showClose,
    open: _open,
    onOpenChange,
  } = props;
  const [open, setOpen] = useState(false);

  const openProps =
    typeof onOpenChange === "function"
      ? {
          open: _open as boolean,
          onOpenChange,
        }
      : {
          open,
          onOpenChange: setOpen,
        };

  return (
    <RadixPopover.Root {...openProps}>
      <RadixPopover.Trigger asChild={isValidElement(trigger)}>
        {trigger}
      </RadixPopover.Trigger>
      <AnimatePresence>
        {openProps.open && (
          <RadixPopover.Portal forceMount>
            <RadixPopover.Content
              asChild
              sideOffset={10}
              align={align}
              side={placement}
              sticky="always"
            >
              <m.div
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                exit={{ opacity: 0 }}
                className={clsxm(
                  "relative z-[999] max-h-[60dvh] max-w-[70dvw] overflow-auto rounded bg-white p-4 shadow-[0_0_16px_2px_#eeeeee50]",
                  contentClassName,
                )}
              >
                {(title || showClose) && (
                  <div className="flex">
                    {title && <span>{title}</span>}
                    {showClose && (
                      <RadixPopover.Close className="ml-auto">
                        <CloseIcon />
                      </RadixPopover.Close>
                    )}
                  </div>
                )}
                <div className="[&:not(:first-child)]:pt-1">{children}</div>
              </m.div>
            </RadixPopover.Content>
          </RadixPopover.Portal>
        )}
      </AnimatePresence>
    </RadixPopover.Root>
  );
}
